package com.meilian.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilian.clients.ProductClient;
import com.meilian.order.mapper.OrderMapper;

import com.meilian.order.service.OrderService;
import com.meilian.param.OrderParam;
import com.meilian.param.PageParam;
import com.meilian.param.ProductCollectParam;
import com.meilian.pojo.Cart;
import com.meilian.pojo.Order;
import com.meilian.pojo.Product;
import com.meilian.to.OrderToProduct;
import com.meilian.utils.R;
import com.meilian.vo.AdminOrderVo;
import com.meilian.vo.CartVo;
import com.meilian.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ProductClient productClient;

    @Autowired
    private OrderMapper orderMapper;
    /**
     * 进行订单数据保存业务
     * 1.将购物车数据转成订单数据
     * 2.进行订单数据的批量插入
     * 3.商品库存修改消息
     * 4.发送购物车库存修改消息
     * @param orderParam
     * @return
     */
    @Override
    public R save(OrderParam orderParam) {


        //直接调用service提供的方法
        //baseMapper内置对象,调用mapper原有方法

        //准备数据
        List<Integer> cartIds=new ArrayList<>();
        List<OrderToProduct> orderToProducts=new ArrayList<>();
        List<Order> orderList=new ArrayList<>();

        //生成数据
        Integer userId=orderParam.getUserId();
        long orderId=System.currentTimeMillis();

        for (CartVo cartVo:orderParam.getProducts()) {
            cartIds.add(cartVo.getId());//保存删除的购物车项的id
            OrderToProduct orderToProduct=new OrderToProduct();
            orderToProduct.setNum(cartVo.getNum());
            orderToProduct.setProductId(cartVo.getProductID());
            orderToProducts.add(orderToProduct);//商品服务修改的数据

            Order order=new Order();
            order.setOrderId(orderId);
            order.setOrderTime(orderId);
            order.setUserId(userId);
            order.setProductId(cartVo.getProductID());
            order.setProductNum(cartVo.getNum());
            order.setProductPrice(cartVo.getPrice());

            orderList.add(order);
        }
        //订单数据批量保存
        saveBatch(orderList);
        //发送购物车消息
        rabbitTemplate.convertAndSend("topic.ex","clear.cart",cartIds);
        //发送商品服务消息
        rabbitTemplate.convertAndSend("topic.ex","sub.number",orderToProducts);

        return R.ok("订单保存成功!");
    }

    /**
     *分组查询订单数据
     *  1.查询用户对应的全部订单
     *  2.利用stream对订单分组  orderId
     *  3.查询订单的全部商品集合,stream组成map
     *  4.封装返回OrderVo对象
     * @param userId
     * @return
     */
    @Override
    public R list(Integer userId) {
        QueryWrapper<Order> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        List<Order> list = list(queryWrapper);//查询全部订单
        //分组(按订单编号)
        Map<Long, List<Order>> orderMap = list.stream().collect(Collectors.groupingBy(Order::getOrderId));
        //查询商品数据(获取商品id集合)
        List<Integer> productIds = list.stream().map(Order::getProductId).collect(Collectors.toList());

        ProductCollectParam productCollectParam=new ProductCollectParam();
        productCollectParam.setProductIds(productIds);
        List<Product> productList = productClient.cartList(productCollectParam);//应该是按商品id查询商品信息

        //把商品集合 按商品id转成map  商品id作为key
        Map<Integer, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getProductId, v -> v));

        //结果封装
        List<List<OrderVo>> result=new ArrayList<>();

        for (List<Order> orders : orderMap.values()) {
            //封装每个订单
            List<OrderVo> orderVos=new ArrayList<>();
            for (Order order:orders){
                OrderVo orderVo=new OrderVo();
                BeanUtils.copyProperties(order,orderVo);
                Product product=productMap.get(order.getProductId());
                orderVo.setProductName(product.getProductName());
                orderVo.setProductPicture(product.getProductPicture());
                orderVos.add(orderVo);
            }
            //把封装好的订单集合放到result集合里
            result.add(orderVos);
        }
        R ok = R.ok("订单数据获取成功!", result);
        log.info("OrderServiceImpl.list业务结束,结果:{}",ok);
        return ok;
    }

    /**
     * 后台管理订单查询数据
     * @param pageParam
     * @return
     */
    @Override
    public R adminList(PageParam pageParam) {

        //分页参数计算完毕
        int offset = (pageParam.getCurrentPage()-1)*pageParam.getPageSize();
        int pageSize = pageParam.getPageSize();

        List<AdminOrderVo>  adminOrderVoList = orderMapper.selectAdminOrder(offset,pageSize);

        return R.ok("订单数据查询成功!",adminOrderVoList);
    }
    /**
     * 检查订单中是否有商品引用
     * @param productId
     * @return
     */
    @Override
    public R check(Integer productId) {
        QueryWrapper<Order> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("product_id",productId);
        Long count = baseMapper.selectCount(queryWrapper);
        if (count>0){
            return R.fail("订单中有 : "+count+"件商品引用,不能删除!");
        }

        return R.ok("无订单引用,可以删除!");
    }
}
